"""\
ConfigureMenuFrame is a class provide a frame to setup controller.
It includes four buttons for controller setting:
    self.btn_Controller_UP for "UP" ->
        self.EventNameListener_Setup(self.btn_Controller_UP, "UP")
    self.btn_Controller_LEFT for "LEFT" ->
        self.EventNameListener_Setup(self.btn_Controller_LEFT, "LEFT")
    self.btn_Controller_RIGHT for "RIGHT" ->
        self.EventNameListener_Setup(self.btn_Controller_RIGHT, "RIGHT")
    self.btn_Controller_FIRE for "RIGHT" ->
        self.EventNameListener_Setup(self.btn_Controller_FIRE, "RIGHT")

And three menu buttons for getting default controller setting, save controller setting,
or back to previous menu:
    btn_Default for "Default" -> self.DefaultConfigureHandle
    btn_Save for "Save" -> self.SaveConfigureHandle
    btn_Back for "Back" -> self.BackToPreviousMenuHandle

and driven state changed in MainMenuFSM

ConfigureMenuFrame.__init__(self)
    Create a ConfigureMenuFrame.
"""

# event name
from Cube.controller.EventDefine import event_ALLCONTROLLEREVENT # event for listen all controller's input
from Shell.fsm.EventDefine import event_MENU_BACKTOPREVIOUS # event for back to previous menu
# controller
from Shell.controller.ControllerConfigure import ControllerEventNameGet, ControllerEventNameSave, ControllerEventNameDefaultGet
from Cube.controller.KeyboardListener import KeyboardListener
from Cube.controller.JoystickControl import JoystickListener
# gui
from Cube.gui.PreludeFinale import DropDownFrame
from direct.gui.DirectGui import DirectFrame, DirectButton
from Cube.gui.DirectGUIPropertiesAccess import BtnTextSet
from Cube.gui.QSizer import ResizedCallBackSet, BoxSizer, Spacer
from Cube.gui.DirectGUIPropertiesAccess import AlignText
# uiString
from Shell.data.UIString import uiString, uiStringScale

class ConfigureMenuFrame(DropDownFrame):
    def __init__(self):
        """\
GameOverMenuFrame.__init__(self)
    Create a GameOverMenuFrame."""
        DropDownFrame.__init__(self)

        self.ControllerEventName = ControllerEventNameGet()

        frame_Board = DirectFrame(parent=self,
                                  frameColor=(0.4,0.4,0.4,0.9),
                                  frameSize=(-0.9,0.9,-0.9,0.9))
        # configure button ------------------------------------------
        self.btnTextScale = uiStringScale["Medium"]
        borderWidth = (0.01,0.01)
        self.btn_Controller_UP = DirectButton(parent=self,
                                              borderWidth = borderWidth,
                                              command= self.EventNameListener_Setup
                                              )

        self.btn_Controller_LEFT = DirectButton(parent=self,
                                                borderWidth = borderWidth,
                                                command= self.EventNameListener_Setup
                                                )

        self.btn_Controller_RIGHT = DirectButton(parent=self,
                                                 borderWidth = borderWidth,
                                                 command= self.EventNameListener_Setup
                                                 )

        self.btn_Controller_FIRE = DirectButton(parent=self,
                                                borderWidth = borderWidth,
                                                command= self.EventNameListener_Setup
                                                )

        self.btn_Controller_UP.uiString = uiString["UP"]
        self.btn_Controller_LEFT.uiString = uiString["LEFT"]
        self.btn_Controller_RIGHT.uiString = uiString["RIGHT"]
        self.btn_Controller_FIRE.uiString = uiString["FIRE"]
        self.AllBtnTextSet()
        # can not move these setting when button creating
        self.btn_Controller_UP["extraArgs"] = [self.btn_Controller_UP, "UP"]
        self.btn_Controller_LEFT["extraArgs"] = [self.btn_Controller_LEFT, "LEFT"]
        self.btn_Controller_RIGHT["extraArgs"] = [self.btn_Controller_RIGHT, "RIGHT"]
        self.btn_Controller_FIRE["extraArgs"] = [self.btn_Controller_FIRE, "FIRE"]
        # -----------------------------------------------------------
        btnCmdText_scale = uiStringScale["Big"]
        btn_Default = DirectButton(parent=self,
                                   borderWidth = borderWidth,
                                   command= self.DefaultConfigureHandle
                                  )
        btn_Save = DirectButton(parent=self,
                                borderWidth = borderWidth,
                                command= self.SaveConfigureHandle
                               )
        btn_Back = DirectButton(parent=self,
                                borderWidth = borderWidth,
                                command= self.BackToPreviousMenuHandle
                                )

        BtnTextSet(btn_Default, uiString["Default"], btnCmdText_scale)
        BtnTextSet(btn_Save, uiString["Save"], btnCmdText_scale)
        BtnTextSet(btn_Back, uiString["Back"], btnCmdText_scale)


        # add gui object into sizer
        sizerConfigureBtn = BoxSizer(BoxSizer.VERTICAL, gap = 0.03)
        sizerConfigureBtn.Add(self.btn_Controller_UP, 1)
        sizerConfigureBtn.Add(self.btn_Controller_LEFT, 1)
        sizerConfigureBtn.Add(self.btn_Controller_RIGHT, 1)
        sizerConfigureBtn.Add(self.btn_Controller_FIRE, 1)

        sizerConfigureBtnMain = BoxSizer(BoxSizer.HORIZONTAL)
        sizerConfigureBtnMain.Add(Spacer(0.15), 0)
        sizerConfigureBtnMain.Add(sizerConfigureBtn, 1)
        sizerConfigureBtnMain.Add(Spacer(0.15), 0)

        sizerActionMenu = BoxSizer(BoxSizer.HORIZONTAL, gap = 0.035)
        sizerActionMenu.Add(btn_Default, 1)
        sizerActionMenu.Add(btn_Save, 1)
        sizerActionMenu.Add(btn_Back, 1)

        sizerMain = BoxSizer(BoxSizer.VERTICAL, gap = 0.05, size=(-0.6,0.6,-0.6,0.6))
        sizerMain.Add(sizerConfigureBtnMain, 5)
        sizerMain.Add(Spacer(0.1), 0)
        sizerMain.Add(sizerActionMenu, 1)
        # alignment gui object's text
        ResizedCallBackSet(self.btn_Controller_UP, AlignText, frame = self.btn_Controller_UP, align = "" )
        ResizedCallBackSet(self.btn_Controller_LEFT, AlignText, frame = self.btn_Controller_LEFT, align = "" )
        ResizedCallBackSet(self.btn_Controller_RIGHT, AlignText, frame = self.btn_Controller_RIGHT, align = "" )
        ResizedCallBackSet(self.btn_Controller_FIRE, AlignText, frame = self.btn_Controller_FIRE, align = "" )
        ResizedCallBackSet(btn_Default, AlignText, frame = btn_Default, align = "" )
        ResizedCallBackSet(btn_Save, AlignText, frame = btn_Save, align = "" )
        ResizedCallBackSet(btn_Back, AlignText, frame = btn_Back, align = "" )
        # do sizer layout
        sizerMain.Layout()

        # -----------------------------------------------------------
        self.PreSelectedBtnText = ""
        self.KeyboardListener = KeyboardListener()
        self.JoystickListener = JoystickListener()

        self.Prelude()

    def EventNameListener_Setup(self, btn, eventName):
        self.PreSelectedBtnTextRestore()

        self.SelectedBtn = btn
        self.SelectedEventName = eventName
        self.PreSelectedBtnText = btnText = btn['text'][0]
        BtnTextSet(btn, "%s: [ ]"%(btn.uiString), self.btnTextScale)
        self.acceptOnce(event_ALLCONTROLLEREVENT,self.EventNameSet)

    def PreSelectedBtnTextRestore(self):
        if self.PreSelectedBtnText:
            BtnTextSet(self.SelectedBtn,self.PreSelectedBtnText, self.btnTextScale)

    def EventNameSet(self, eventName):
        self.ControllerEventName[self.SelectedEventName] = eventName
        BtnTextSet(self.SelectedBtn, "%s: [%s]"%(self.SelectedBtn.uiString, eventName), self.btnTextScale)
        self.PreSelectedBtnText = ""
        #self.ignore(event_ALLCONTROLLEREVENT)  # acceptOnce
        #print eventName
    # -----------------------------------------------------------
    def AllBtnTextSet(self):
        for (btn,eventName) in [(self.btn_Controller_UP,self.ControllerEventName["UP"]),
                                (self.btn_Controller_LEFT,self.ControllerEventName["LEFT"]),
                                (self.btn_Controller_RIGHT,self.ControllerEventName["RIGHT"]),
                                (self.btn_Controller_FIRE,self.ControllerEventName["FIRE"])]:
            BtnTextSet(btn,"%s: [%s]"%(btn.uiString,eventName), self.btnTextScale)
    # -----------------------------------------------------------
    def DefaultConfigureHandle(self):
        self.ControllerEventName = ControllerEventNameDefaultGet()
        self.AllBtnTextSet()

    def SaveConfigureHandle(self):
        ControllerEventNameSave(self.ControllerEventName)

    def BackToPreviousMenuHandle(self):
        self.KeyboardListener.ignoreAll()
        self.JoystickListener.ignoreAll()
        self.ignoreAll()
        messenger.send(event_MENU_BACKTOPREVIOUS) # event for back to previous menu

    # -----------------------------------------------------------
    def destroy(self):
        self.btn_Controller_UP["extraArgs"] = []
        self.btn_Controller_LEFT["extraArgs"] = []
        self.btn_Controller_RIGHT["extraArgs"] = []
        self.btn_Controller_FIRE["extraArgs"] = []
        DropDownFrame.destroy(self)
